#include "headers/Operacoes.h"

#include <stdio.h>
#include <stdlib.h>

float totalOperations = TOTAL_OPERATIONS;
float totalWriteOperationsPercent = TOTAL_WRITE_OPERATIONS_PERCENT;
float totalReadOperations;
float totalWriteOperations;
float totalReadOperationsRemaining;
float totalWriteOperationsRemaining;

int read_count_remaining=0;
int write_count_remaining=0;

char opType;
int i, pageId;
int totalPages = NUMERO_DE_PAGINAS;

float getTotalOperations(float totalOperations, float totalWriteOperationsPercent, char operationType){
        float totalWriteOperations=totalOperations*(totalWriteOperationsPercent/100);
        float totalReadOperations=totalOperations-totalWriteOperations;
        if(operationType=='W'){
        		return totalWriteOperations;
        	}else if(operationType=='R'){
        		return totalReadOperations;
        	}
}

char getOperationType(int writeAffinity){
	int num;
	num=rand()%100;

	//printf("\nNum = %d",num);
	if(num<=writeAffinity)
			return 'W';
	return 'R';
}

int random_in_range (unsigned int min, unsigned int max)
{
  int base_random = rand(); /* in [0, RAND_MAX] */
  if (RAND_MAX == base_random) return random_in_range(min, max);
  /* now guaranteed to be in [0, RAND_MAX) */
  int range       = max - min,
      remainder   = RAND_MAX % range,
      bucket      = RAND_MAX / range;
  /* There are range buckets, plus one smaller interval
     within remainder of RAND_MAX */
  if (base_random < RAND_MAX - remainder) {
    return min + base_random/bucket;
  } else {
    return random_in_range (min, max);
  }
}

unsigned int randr(unsigned int min, unsigned int max)
{
       double scaled = (double)rand()/RAND_MAX;
       return (max - min +1)*scaled + min;
}


int getRandomNumber(int minRange, int maxRange,int codRandomGenerator){
	switch (codRandomGenerator){
	case 1:
		return randr(minRange,maxRange);
		break;
	case 2:
		return random_in_range(minRange,maxRange);
		break;
	}
}


int initRemainingOperations(){

	totalWriteOperations=(int)getTotalOperations(totalOperations,totalWriteOperationsPercent,'W');
	totalReadOperations=(int)getTotalOperations(totalOperations,totalWriteOperationsPercent,'R');

	read_count_remaining=(int)totalReadOperations;
	write_count_remaining=(int)totalWriteOperations;

}

int generateOperations(int* chosenPageId, char* chosenOpType) {

	totalWriteOperations=(int)getTotalOperations(totalOperations,totalWriteOperationsPercent,'W');
	totalReadOperations=(int)getTotalOperations(totalOperations,totalWriteOperationsPercent,'R');

	opType=getOperationType(totalWriteOperationsPercent);
	pageId=getRandomNumber(0,totalPages,2);

	if(read_count_remaining==0){
		opType='W';
	} else if(write_count_remaining==0){
		opType='R';
	}

	if(opType=='R'){//&& totalReadOperationsRemaining>0
		read_count_remaining--;
	}else if(opType=='W'){// && totalWriteOperationsRemaining>0
		write_count_remaining--;
	}


	/*
	puts("\n\n**************************************\n") ;
	printf("Total Write Operations: %i\n",(int)totalWriteOperations);
	printf("Total Read Operations: %i\n",(int)totalReadOperations);
	puts("___________________________________________\n");
	printf("Operation Type: %c\n",opType);
	printf("Selected Page Id: %i\n",pageId);
	puts("___________________________________________\n");
	printf("Total Write Operations Remaining: %i\n",(int)write_count_remaining);
	printf("Total Read Operations Remaining: %i\n",(int)read_count_remaining);
	puts("\n\n*****************************************************************************\n") ;
*/

	*chosenOpType = opType;
	*chosenPageId = pageId;

	return EXIT_SUCCESS;

}
